package com.xtaller.sdboot.controller; 

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xtaller.sdboot.core.R;
import com.xtaller.sdboot.core.Status;
import com.xtaller.sdboot.core.base.BaseEntity;
import com.xtaller.sdboot.entity.IamDepartment;
import com.xtaller.sdboot.entity.IamDepartmentUser;
import com.xtaller.sdboot.entity.IamUser;
import com.xtaller.sdboot.service.IamDepartmentService;
import com.xtaller.sdboot.service.IamDepartmentUserService;
import com.xtaller.sdboot.service.IamUserService;
import com.xtaller.sdboot.utils.annotation.Permission;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import com.xtaller.sdboot.utils.helper.ListHelper;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.xtaller.sdboot.core.base.BaseController;
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
import io.swagger.annotations.ApiParam;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/** 
* 代码生成 
* @author: Taller  
* @date: 2020-03-30 09:57:22
* @Description: 组织架构控制器 
*/ 
@Api(tags = "组织架构控制器") 
@RestController 
@RequestMapping("/v1/iam/department") 
public class IamDepartmentController extends BaseController<IamDepartment> { 
    @Autowired private IamDepartmentService iamDepartmentService;
    @Autowired private IamDepartmentUserService iamDepartmentUserService;
    @Autowired private IamUserService userService;

    @ApiOperation("查询用户")
    @Permission(authorities = "iam:department:user:data:query")
    @GetMapping("/users/query/key")
    public Object queryByKey(@RequestParam(value = "key", required = false, defaultValue = "0") String key){
        return R.ok(iamDepartmentService.findUserByKey(key, applicationId.get()));
    }
    @ApiOperation("分配用户")
    @Permission(authorities = "iam:department:user:set")
    @PostMapping("/users/set")
    public Object setUser(@RequestBody JSONObject obj){
        var qw = new QueryWrapper<IamDepartmentUser>();
        qw.lambda()
                .eq(IamDepartmentUser::getUserId, obj.getString("userId"))
                .eq(IamDepartmentUser::getDeptId, obj.getString("departmentId"));
        if(iamDepartmentUserService.getList(qw).size() > 0){
            return R.error(Status.BAD_REQUEST, "用户已加入该组织");
        }
        var model = new IamDepartmentUser();
        model.setUserId(obj.getString("userId"));
        model.setAppId(applicationId.get());
        model.setDeptId(obj.getString("departmentId"));
        if(iamDepartmentUserService.model(model)){
            return R.ok("加入成功");
        }
        return R.error(Status.BAD_REQUEST, "加入失败");
    }

    @ApiOperation("移出用户")
    @Permission(authorities = "iam:department:user:remove")
    @PutMapping("/users/set")
    public Object removeUser(@RequestBody JSONObject obj){
        var qw = new QueryWrapper<IamDepartmentUser>();
        qw.lambda()
                .eq(IamDepartmentUser::getUserId, obj.getString("userId"))
                .eq(IamDepartmentUser::getDeptId, obj.getString("departmentId"));
        var list = iamDepartmentUserService.getList(qw);
        if(list.size() == 0){
            return R.error(Status.BAD_REQUEST, "用户不在该组织中");
        }
        var model = list.get(0);

        if(iamDepartmentUserService.delete(model.getId())){
            return R.ok("移出成功");
        }
        return R.error(Status.BAD_REQUEST, "移出失败");
    }



    @ApiOperation("表格") 
    @Permission(authorities = "iam:department:data:list")
    @Override
    public Object getByPage(HttpServletRequest request) throws Exception {

        return super.getByPage(request);
    } 
 
    @ApiOperation("创建")
    @Permission(authorities = "iam:department:opt:create")
    @Override
    public Object createEntity(@Valid @RequestBody IamDepartment entity, HttpServletRequest request) throws Exception {
        return super.createEntity(entity, request);
    } 
 
    @ApiOperation("修改")
    @Permission(authorities = "iam:department:opt:update") 
    @Override
    public Object updateEntity(@PathVariable("id") Serializable id, @Valid @RequestBody IamDepartment entity, HttpServletRequest request) throws Exception {
        return super.updateEntity(id, entity, request);
    } 
 
    @ApiOperation("删除")
    @Permission(authorities = "iam:department:opt:delete")
    @Override
    public Object deleteEntity(@PathVariable("id") Serializable id, HttpServletRequest request) throws Exception {
        return super.deleteEntity(id, request);
    }

    @ApiOperation("读取部门员工数据")
    @GetMapping("/users")
    @Permission(authorities = "iam:department:user:data:list")
    public Object tableUser(@RequestParam(value = "deptId", required = false, defaultValue = "0") String deptId,
                            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
                            @RequestParam(value = "limit", required = false, defaultValue = "100") int limit){
        var p = new Page<IamDepartmentUser>(page, limit);
        var qw = new QueryWrapper<IamDepartmentUser>();
        qw.lambda()
                .eq(IamDepartmentUser::getDeptId, deptId);
        var data = iamDepartmentUserService.pages(p, qw);
        JSONObject depts = (JSONObject) p2t.apply(data);
        var uds = data.getRecords();

        var list = JsonHelper.list();
        if(uds.size() > 0){
            var userIds = uds.stream()
                    .map(m -> m.getUserId())
                    .distinct()
                    .collect(Collectors.toList());
            var users = userService.getByIds(userIds);
            if(users.size() > 0){
                uds.stream().forEach(x -> {
                    var u = f2u(users, x.getUserId());
                    if(u != null){
                        list.add(u);
                    }
                });
            }
        }
        depts.put("data", list);
        return depts;
    }

    @Override
    protected String beforeCreate(BaseEntity entity) throws Exception {
        var model = (IamDepartment) entity;
        model.setAppId(applicationId.get());
        var qw = new QueryWrapper<IamDepartment>();
        qw.lambda()
                .eq(IamDepartment::getAppId, model.getAppId())
                .eq(IamDepartment::getName, model.getName());
        if(iamDepartmentService.getList(qw).size() > 0){
            return "组织架构名称已经存在";
        }
        return super.beforeCreate(entity);
    }

    @Override
    protected String beforeUpdate(BaseEntity entity) throws Exception {
        var model = (IamDepartment) entity;
        model.setAppId(applicationId.get());
        var qw = new QueryWrapper<IamDepartment>();
        qw.lambda()
                .ne(BaseEntity::getId, model.getId())
                .eq(IamDepartment::getAppId, model.getAppId())
                .eq(IamDepartment::getName, model.getName());
        if(iamDepartmentService.getList(qw).size() > 0){
            return "组织架构名称已经存在";
        }

        return super.beforeUpdate(entity);
    }

    @Override
    protected String beforeDelete(BaseEntity entity) throws Exception {
        var qw = new QueryWrapper<IamDepartmentUser>();
        qw.lambda()
                .eq(IamDepartmentUser::getDeptId, entity.getId());
        if(iamDepartmentUserService.getList(qw).size() > 0){
            return "该组织架构下有人员信息,禁止直接删除";
        }
        return super.beforeDelete(entity);
    }

    @Override
    protected String beforePage(Map params) throws Exception {
        var qw = new QueryWrapper<IamDepartment>();
        qw.lambda()
                .eq(IamDepartment::getAppId, applicationId.get());
        if(iamDepartmentService.getList(qw).size() == 0){
            var dept = new IamDepartment();
            dept.setAppId(applicationId.get());
            dept.setName("总经办");
            dept.setParentId("0");
            iamDepartmentService.model(dept);
        }
        return super.beforePage(params);
    }

    @Override
    protected JSONObject afterPage(JSONObject json) throws Exception {
        var list = JsonHelper.o2l(json.get("data"));
        list.stream().forEach(x -> {
            x.put("title", x.getString("name"));
        });
        var data = JsonHelper.create("list", list)
                .put("tree", ListHelper.list2Tree(list, "0"));
        return super.afterPage(data);
    }


    private JSONObject f2u(List<IamUser> users, String userId){
        var opt = users.stream()
                .filter(u -> u.getId().equals(userId))
                .filter(Objects::nonNull)
                .findFirst();
        if(opt.isPresent()){
            var model = opt.get();
            var user = JsonHelper.create("trueName", model.getRealName())
                    .put("mobile", model.getMobile())
                    .put("id", model.getId());
            return user;
        }
        return null;
    }
}
